// DOM 元素
const guidewireSpeedInput = document.getElementById('guidewire-speed');
const guidewireSpeedValue = document.getElementById('guidewire-speed-value');
const catheterSpeedInput = document.getElementById('catheter-speed');
const catheterSpeedValue = document.getElementById('catheter-speed-value');

const btnPushGuidewire = document.getElementById('btn-push-guidewire');
const btnRetractGuidewire = document.getElementById('btn-retract-guidewire');
const btnRotateCW = document.getElementById('btn-rotate-cw');
const btnRotateCCW = document.getElementById('btn-rotate-ccw');
const btnRotateCWPUSH = document.getElementById('btn-rotate-cw-push');
const btnRotateCCWPush = document.getElementById('btn-rotate-ccw-push');
const btnPushCatheter = document.getElementById('btn-push-catheter');
const btnRetractCatheter = document.getElementById('btn-retract-catheter');
const btnStopAll = document.getElementById('btn-stop-all');
const btnPing = document.getElementById('btn-ping');
const btnClearLog = document.getElementById('btn-clear-log');

const logContent = document.getElementById('log-content');
const statusElement = document.getElementById('status');
const dsaCanvas = document.getElementById('dsa-canvas');
const dsaVideo = document.getElementById('dsa-video');

// 设置相关 DOM 元素
const btnSettings = document.getElementById('btn-settings');
const settingsModal = document.getElementById('settings-modal');
const btnCloseSettings = document.getElementById('btn-close-settings');
const btnCancelSettings = document.getElementById('btn-cancel-settings');
const comPortInput = document.getElementById('com-port-input');
const videoStreamInput = document.getElementById('video-stream-input');
const btnSaveComPort = document.getElementById('btn-save-com-port');
const btnSaveVideoStream = document.getElementById('btn-save-video-stream');
const currentComPort = document.getElementById('current-com-port');
const currentVideoStream = document.getElementById('current-video-stream');
// 端口扫描 DOM
const btnScanPorts = document.getElementById('btn-scan-ports');
const scanOutput = document.getElementById('scan-output');

// 配置存储（从服务器加载）
let settings = {
    comPort: 'COM3',
    videoStream: 'http://localhost:8080/?action=snapshot'
};

// 从服务器加载配置
async function loadSettingsFromServer() {
    try {
        const response = await fetch('/api/get_config');
        const data = await response.json();
        if (data.status === 'success') {
            settings = data.config;
            console.log('✓ 配置已从服务器加载:', settings);
            // 更新视频流
            if (dsaVideo) {
                dsaVideo.src = settings.videoStream || 'http://localhost:8080/?action=snapshot';
            }
        } else {
            console.warn('获取配置失败:', data.message);
        }
    } catch (error) {
        console.error('加载配置时出错:', error);
    }
}

// 速度输入监听
guidewireSpeedInput.addEventListener('input', (e) => {
    guidewireSpeedValue.textContent = e.target.value;
});

catheterSpeedInput.addEventListener('input', (e) => {
    catheterSpeedValue.textContent = e.target.value;
});

// 设置模态框控制
function showSettings() {
    settingsModal.classList.add('show');
    comPortInput.value = settings.comPort;
    videoStreamInput.value = settings.videoStream;
    updateCurrentSettings();
}

function hideSettings() {
    settingsModal.classList.remove('show');
}

function updateCurrentSettings() {
    currentComPort.textContent = settings.comPort;
    currentVideoStream.textContent = settings.videoStream;
}

// 设置按钮事件
btnSettings.addEventListener('click', showSettings);
btnCloseSettings.addEventListener('click', hideSettings);
btnCancelSettings.addEventListener('click', hideSettings);

// 点击模态框外部关闭
settingsModal.addEventListener('click', (e) => {
    if (e.target === settingsModal) {
        hideSettings();
    }
});

// 保存 COM 端口设置
btnSaveComPort.addEventListener('click', async () => {
    const newPort = comPortInput.value.trim();
    if (newPort) {
        updateCurrentSettings();
        addLog(`✓ COM 端口已更新为: ${newPort}`, 'success');
        // 调用后端 API 更新串口
        await updateSerialPort(newPort);
    } else {
        addLog('✗ 请输入有效的 COM 端口号', 'error');
    }
});

// 保存视频流设置
btnSaveVideoStream.addEventListener('click', async () => {
    const newStream = videoStreamInput.value.trim();
    if (newStream) {
        // 先更新服务器配置
        try {
            const response = await fetch('/api/update_video_stream', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ stream: newStream })
            });
            const data = await response.json();
            if (data.status === 'success') {
                settings.videoStream = newStream;
                updateCurrentSettings();
                addLog(`✓ 视频流地址已更新: ${newStream}`, 'success');
                // 更新视频源
                updateVideoStream(newStream);
            } else {
                addLog(`✗ 更新失败: ${data.message}`, 'error');
            }
        } catch (error) {
            addLog(`✗ 更新视频流失败: ${error.message}`, 'error');
        }
    } else {
        addLog('✗ 请输入有效的视频流地址', 'error');
    }
});

// 更新视频流显示
function updateVideoStream(url) {
    dsaVideo.src = url;
    dsaVideo.style.display = 'block';
    dsaCanvas.style.display = 'none';
}

// 更新串口（调用后端 API）
async function updateSerialPort(port) {
    try {
        const response = await fetch('/api/update_serial_port', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ port: port })
        });
        const data = await response.json();
        if (data.status === 'success') {
            settings.comPort = port;
            addLog(`✓ 串口设置已保存: ${port}`, 'success');
        } else {
            addLog(`⚠ 服务器响应: ${data.message}`, 'warning');
        }
    } catch (error) {
        addLog(`✗ 更新串口失败: ${error.message}`, 'error');
    }
}

// 扫描端口（调用后端）
async function scanPorts() {
    if (!btnScanPorts || !scanOutput) return;
    btnScanPorts.disabled = true;
    scanOutput.value = '正在扫描... 请稍候。';
    try {
        const resp = await fetch('/api/scan_ports');
        const data = await resp.json();
        if (data.status === 'success') {
            scanOutput.value = data.output || '未返回任何输出';
            addLog('✓ 端口扫描完成', 'info');
        } else {
            scanOutput.value = '扫描失败: ' + (data.message || '未知错误');
            addLog('✗ 端口扫描失败: ' + (data.message || ''), 'error');
        }
    } catch (err) {
        scanOutput.value = '请求出错: ' + (err.message || String(err));
        addLog('✗ 扫描请求错误: ' + (err.message || String(err)), 'error');
    } finally {
        btnScanPorts.disabled = false;
    }
}

if (btnScanPorts) {
    btnScanPorts.addEventListener('click', () => {
        scanPorts();
    });
}

// 添加日志
function addLog(message, type = 'info') {
    const now = new Date();
    const timeStr = now.toLocaleTimeString('zh-CN');
    
    const logItem = document.createElement('div');
    logItem.className = `log-item log-${type}`;
    
    const timeSpan = document.createElement('span');
    timeSpan.className = 'log-time';
    timeSpan.textContent = `[${timeStr}]`;
    
    const messageSpan = document.createElement('span');
    messageSpan.className = 'log-message';
    messageSpan.textContent = message;
    
    logItem.appendChild(timeSpan);
    logItem.appendChild(messageSpan);
    logContent.appendChild(logItem);
    
    // 自动滚动到底部
    logContent.scrollTop = logContent.scrollHeight;
}

// 清空日志
btnClearLog.addEventListener('click', () => {
    logContent.innerHTML = '';
    addLog('日志已清空', 'info');
});

// 发送控制命令
async function sendCommand(endpoint, speed = null) {
    try {
        const options = {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            }
        };
        
        if (speed !== null) {
            options.body = JSON.stringify({ speed: speed });
        }
        
        const response = await fetch(`/api/${endpoint}`, options);
        const data = await response.json();
        
        if (data.status === 'success') {
            addLog(data.message, 'success');
            return true;
        } else {
            addLog(`失败: ${data.message}`, 'error');
            return false;
        }
    } catch (error) {
        addLog(`错误: ${error.message}`, 'error');
        return false;
    }
}

// 绑定按钮事件（按住持续发送，每 0.5s；松开发送停止指令）
const holdIntervalMs = 500;
const holdTimers = new Map();

function startHoldForKey(key, endpoints, getSpeed) {
    // endpoints: array of endpoint strings
    // 只有当key不存在时才停止之前的动作，避免重复触发停止命令
    if (!holdTimers.has(key)) {
        const sendOnce = () => {
            const sp = typeof getSpeed === 'function' ? getSpeed() : getSpeed;
            endpoints.forEach(ep => sendCommand(ep, sp));
        };
        sendOnce();
        const t = setInterval(sendOnce, holdIntervalMs);
        holdTimers.set(key, t);
    }
}

function stopHoldForKey(key) {
    const t = holdTimers.get(key);
    if (t) {
        clearInterval(t);
        holdTimers.delete(key);
    }
    // 仅当没有任何活动定时器时再发送停止指令，避免影响其它正在按住的按钮
    if (holdTimers.size === 0) {
        sendCommand('stop_all');
    }
}

function bindHoldMultiButton(el, endpoints, getSpeed) {
    if (!el) return;
    const key = el.id || Symbol();
    const start = (e) => { e.preventDefault(); startHoldForKey(key, endpoints, getSpeed); };
    // 只有当该 key 有活动定时器时才执行结束逻辑，避免 hover/mouseleave 导致误触发
    const end = (e) => {
        e.preventDefault();
        if (holdTimers.has(key)) {
            stopHoldForKey(key);
        }
    };

    // Prefer Pointer Events (unified) to avoid duplicated mouse/touch events and to use pointer capture
    if (window.PointerEvent) {
        el.addEventListener('pointerdown', (e) => {
            e.preventDefault();
            try { el.setPointerCapture(e.pointerId); } catch (err) {}
            start(e);
        });
        el.addEventListener('pointerup', (e) => {
            e.preventDefault();
            try { el.releasePointerCapture(e.pointerId); } catch (err) {}
            end(e);
        });
        el.addEventListener('pointercancel', (e) => {
            e.preventDefault();
            try { el.releasePointerCapture(e.pointerId); } catch (err) {}
            end(e);
        });
    } else {
        // Fallback: mouse/touch. Avoid mouseleave causing stop while still pressed.
        el.addEventListener('mousedown', start);
        el.addEventListener('touchstart', start, { passive: false });

        el.addEventListener('mouseup', end);
        el.addEventListener('touchend', end);
        el.addEventListener('touchcancel', end);
    }
}

// 单动作按钮使用多动作绑定（仅一个 endpoint）
bindHoldMultiButton(btnPushGuidewire, ['push_guidewire'], () => parseFloat(guidewireSpeedInput.value));
bindHoldMultiButton(btnRetractGuidewire, ['retract_guidewire'], () => parseFloat(guidewireSpeedInput.value));
bindHoldMultiButton(btnRotateCW, ['rotate_guidewire_cw'], () => parseFloat(guidewireSpeedInput.value));
bindHoldMultiButton(btnRotateCCW, ['rotate_guidewire_ccw'], () => parseFloat(guidewireSpeedInput.value));
bindHoldMultiButton(btnPushCatheter, ['push_catheter'], () => parseFloat(catheterSpeedInput.value));
bindHoldMultiButton(btnRetractCatheter, ['retract_catheter'], () => parseFloat(catheterSpeedInput.value));

// 新增：边旋转边推进（组合动作）
bindHoldMultiButton(btnRotateCWPUSH, ['rotate_guidewire_cw', 'push_guidewire'], () => parseFloat(guidewireSpeedInput.value));
bindHoldMultiButton(btnRotateCCWPush, ['rotate_guidewire_ccw', 'push_guidewire'], () => parseFloat(guidewireSpeedInput.value));

// 保留紧急停止按钮的单击行为
btnStopAll.addEventListener('click', () => {
    // 停止所有定时器
    for (const key of Array.from(holdTimers.keys())) {
        stopHoldForKey(key);
    }
});

btnPing.addEventListener('click', async () => {
    try {
        const response = await fetch('/api/ping');
        const data = await response.json();
        
        if (data.status === 'success') {
            addLog('机器人在线 ✓', 'success');
            statusElement.textContent = '连接状态: 已连接';
            statusElement.className = 'status-connected';
        } else {
            addLog('机器人离线 ✗', 'error');
            statusElement.textContent = '连接状态: 未连接';
            statusElement.className = 'status-disconnected';
        }
    } catch (error) {
        addLog(`连接检测失败: ${error.message}`, 'error');
        statusElement.textContent = '连接状态: 未连接';
        statusElement.className = 'status-disconnected';
    }
});

// DSA 影像模拟
function initializeDSACanvas() {
    const ctx = dsaCanvas.getContext('2d');
    
    // 绘制医学影像背景
    const gradient = ctx.createLinearGradient(0, 0, dsaCanvas.width, dsaCanvas.height);
    gradient.addColorStop(0, '#2c3e50');
    gradient.addColorStop(1, '#1a252f');
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, dsaCanvas.width, dsaCanvas.height);
    
    // 绘制网格
    ctx.strokeStyle = 'rgba(52, 152, 219, 0.1)';
    ctx.lineWidth = 1;
    
    for (let i = 0; i < dsaCanvas.width; i += 40) {
        ctx.beginPath();
        ctx.moveTo(i, 0);
        ctx.lineTo(i, dsaCanvas.height);
        ctx.stroke();
    }
    
    for (let i = 0; i < dsaCanvas.height; i += 40) {
        ctx.beginPath();
        ctx.moveTo(0, i);
        ctx.lineTo(dsaCanvas.width, i);
        ctx.stroke();
    }
    
    // 绘制中心十字
    ctx.strokeStyle = 'rgba(52, 152, 219, 0.3)';
    ctx.lineWidth = 2;
    
    ctx.beginPath();
    ctx.moveTo(dsaCanvas.width / 2, 0);
    ctx.lineTo(dsaCanvas.width / 2, dsaCanvas.height);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.moveTo(0, dsaCanvas.height / 2);
    ctx.lineTo(dsaCanvas.width, dsaCanvas.height / 2);
    ctx.stroke();
    
    // 绘制模拟导丝
    ctx.strokeStyle = '#e74c3c';
    ctx.lineWidth = 3;
    ctx.beginPath();
    ctx.moveTo(dsaCanvas.width / 2, 100);
    
    // 绘制一条蜿蜒的导丝路径
    for (let y = 100; y < dsaCanvas.height; y += 20) {
        const x = dsaCanvas.width / 2 + Math.sin(y / 30) * 40;
        ctx.lineTo(x, y);
    }
    ctx.stroke();
    
    // 绘制模拟导管
    ctx.strokeStyle = 'rgba(52, 152, 219, 0.6)';
    ctx.lineWidth = 8;
    ctx.beginPath();
    ctx.moveTo(dsaCanvas.width / 2, 80);
    ctx.lineTo(dsaCanvas.width / 2, dsaCanvas.height - 50);
    ctx.stroke();
    
    // 绘制导丝头部
    ctx.fillStyle = '#e74c3c';
    ctx.beginPath();
    ctx.arc(dsaCanvas.width / 2 + Math.sin(dsaCanvas.height / 30) * 40, dsaCanvas.height - 30, 5, 0, Math.PI * 2);
    ctx.fill();
    
    // 添加文本信息
    ctx.fillStyle = 'rgba(52, 152, 219, 0.5)';
    ctx.font = '12px Arial';
    ctx.fillText('DSA 实时影像 - 模拟显示', 10, 20);
    ctx.fillText(`时间: ${new Date().toLocaleTimeString('zh-CN')}`, 10, dsaCanvas.height - 10);
}

// 页面加载完成时初始化
document.addEventListener('DOMContentLoaded', async () => {
    // 从服务器加载配置
    await loadSettingsFromServer();
    
    // 初始化视频流
    updateVideoStream(settings.videoStream);
    updateCurrentSettings();
    addLog('欢迎使用介入手术机器人控制系统', 'info');
    addLog(`已加载视频流: ${settings.videoStream}`, 'info');
    addLog(`已加载 COM 端口: ${settings.comPort}`, 'info');
    
    // 只在页面加载时检测一次连接状态，而不是定期检测
    btnPing.click();
});

// 键盘快捷键
document.addEventListener('keydown', (e) => {
    // 空格 = 紧急停止
    if (e.code === 'Space' && e.target === document.body) {
        e.preventDefault();
        btnStopAll.click();
        addLog('触发紧急停止 (快捷键: Space)', 'warning');
    }
    
    // 按 'S' 打开设置
    if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        showSettings();
    }
});

